//
// Created by hsj on 2024-1-15.
// 无论复制出多少文件描述符，均应调用shutdown函数发送EOF并进入半关闭状态。


#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>

#ifdef WIN32
//windows minGW64
//inet_pton函数：_WIN32_WINNT
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600
#include <winsock2.h>
#include <ws2tcpip.h>
//#pragma comment(lib,"ws2_32.lib")
#else
//linux  gcc
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#endif
#define BUF_SIZE 100
void error_handling(char *buf);
int main(int argc,char *argv[]){
    int serv_sock, clnt_sock;
    FILE * readfp;
    FILE * writefp;
    struct sockaddr_in serv_adr, clnt_adr;
    socklen_t clnt_adr_sz;
    char buf[BUF_SIZE]={0};
    char port[] = "3399";

    serv_sock=socket(PF_INET, SOCK_STREAM, 0);
    memset(&serv_adr, 0, sizeof(serv_adr));
    serv_adr.sin_family=AF_INET;
    serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
    serv_adr.sin_port=htons(atoi(/*argv[1]*/port));

    bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr));

    listen(serv_sock, 128);

    clnt_adr_sz=sizeof(clnt_adr);
    clnt_sock=accept(serv_sock, (struct sockaddr* )&clnt_adr ,&clnt_adr_sz);

    readfp=fdopen(clnt_sock, "r");
    writefp=fdopen(dup(clnt_sock), "w");//复制文件描述符fd

    fputs("FROM SERVER: Hi~ client? \n", writefp);
    fputs("I love all of the world \n", writefp);
    fputs("You are awesome! \n", writefp);//awesome:很好的
    fflush(writefp);
    shutdown(fileno(writefp), SHUT_WR);//FILE指针转fd: 无论复制出多少文件描述符，均应调用shutdown函数发送EOF并进入半关闭状态。
    fclose(writefp);

    fgets(buf, sizeof(buf), readfp);
    fputs(buf, stdout);//标准输出
    fclose(readfp);

    return EXIT_SUCCESS;
}

void error_handling( char *message){
    fputs (message, stderr);
    fputc('\n', stderr);
    exit(1);
}